package tcc.wa.persistence.dao;

import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import tcc.wa.model.GeographicCoordinate;
import tcc.wa.model.HourlyWeatherForecast;
import tcc.wa.model.Location;
import tcc.wa.persistence.dao.base.DAOBase;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

/**
 * Data access object class responsible for HourlyWeatherForecasts
 * persistence management.
 */
public class HourlyWeatherForecastDAO extends DAOBase {
	
	/** The find last hourly weather forecast string. */
	private final String findLastHourlyWeatherForecastString = 
			"SELECT * FROM " + FORECAST_TABLE_NAME + " f INNER JOIN " + HOURLY_WEATHER_FORECAST_TABLE_NAME + " hwf ON hwf.forecast_id = f.id " +
					"INNER JOIN " + LOCATION_TABLE_NAME + " l ON f.location_id = l.id";
	
	public HourlyWeatherForecastDAO(Context context) {
		super(context);
	}
	
	/**
	 * Saves a list of hourly weather forecasts on the database.
	 *
	 * @param hourlyForecasts the list of hourly forecasts
	 */
	public void save(List<HourlyWeatherForecast> hourlyForecasts) {
		clearPreviousForecasts();
		SQLiteDatabase database = getWritableDatabase();
		for (HourlyWeatherForecast hourlyForecast : hourlyForecasts) {
			ContentValues forecastValues = new ContentValues();
			forecastValues.put("location_id", hourlyForecast.getLocation().getId());
			forecastValues.put("date", hourlyForecast.getDate().getTime());
			long forecastId = database.insert(FORECAST_TABLE_NAME, null, forecastValues);
			ContentValues hourlyForecastValues = new ContentValues();
			hourlyForecastValues.put("forecast_id", forecastId);
			hourlyForecastValues.put("relative_humidity", hourlyForecast.getRelativeHumidity());
			hourlyForecastValues.put("precipitation", hourlyForecast.getPrecipitation());
			hourlyForecastValues.put("temperature", hourlyForecast.getTemperature());
			long hourlyForecastId = database.insert(HOURLY_WEATHER_FORECAST_TABLE_NAME, null, hourlyForecastValues);
			hourlyForecast.setForecastId(forecastId);
			hourlyForecast.setHourlyWeatherForecastId(hourlyForecastId);
		}
		close();
	}
	
	/**
	 * Finds the last saved hourly weather forecasts.
	 *
	 * @return the list of last saved hourly weather forecasts.
	 */
	public List<HourlyWeatherForecast> findLast() {
		List<HourlyWeatherForecast> hourlyForecasts = new ArrayList<HourlyWeatherForecast>();
		SQLiteDatabase database = getWritableDatabase();
		Cursor cursor = database.rawQuery(findLastHourlyWeatherForecastString, null);
		while (cursor.moveToNext()) {
			HourlyWeatherForecast hourlyForecast = new HourlyWeatherForecast();
			hourlyForecast.setForecastId(cursor.getLong(0));
			hourlyForecast.setDate(new Date(cursor.getLong(1)));
			hourlyForecast.setHourlyWeatherForecastId(cursor.getLong(3));
			hourlyForecast.setRelativeHumidity(cursor.getDouble(5));
			hourlyForecast.setPrecipitation(cursor.getDouble(6));
			hourlyForecast.setTemperature(cursor.getDouble(7));
			Location location = new Location();
			location.setId(cursor.getLong(8));
			location.setCity(cursor.getString(9));
			location.setState(cursor.getString(10));
			location.setRegion(cursor.getString(11));
			location.setCountry(cursor.getString(12));
			location.setGeographicCoordinate(new GeographicCoordinate(cursor.getDouble(13), cursor.getDouble(14)));
			hourlyForecast.setLocation(location);
			hourlyForecasts.add(hourlyForecast);
		}
		close();
		return hourlyForecasts;
	}
	
	/**
	 * Clear previous forecasts.
	 */
	private void clearPreviousForecasts() {
		SQLiteDatabase database = getWritableDatabase();
		List<Long> forecastIds = new ArrayList<Long>();
		Cursor cursor = database.query(HOURLY_WEATHER_FORECAST_TABLE_NAME, new String[] { "forecast_id" }, null, null, null, null, null);
		while (cursor.moveToNext())
			forecastIds.add(cursor.getLong(0));
		database.delete(HOURLY_WEATHER_FORECAST_TABLE_NAME, null, null);
		for (long forecastId : forecastIds)
			database.delete(FORECAST_TABLE_NAME, "id=?", new String[] { String.valueOf(forecastId) });
		close();
	}
}